//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Text;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using CommunityServer.Components;
using CommunityServer.Controls;
using CommunityServer.Galleries.Components;

namespace CommunityServer.Galleries.Controls
{
	/// <summary>
	/// Summary description for SearchResults.
	/// </summary>
	public class SearchResults : GalleryTemplatedWebControl
	{

		#region Child Controls

		private int[] searchSections = null;
		private int[] searchUsers = null;
		private CSContext cSContext;

		private IText searchFor;
		private TextBox searchTextTop;
		private TextBox searchTextBottom;
		private IButton searchButtonTop;
		private IButton searchButtonBottom;
		private DataList searchDataList;
		private CurrentPage resultTotal;
		private IText searchDuration;
		private Pager pager;
		private HtmlGenericControl validatorTop;
		private HtmlGenericControl validatorBottom;

		#endregion

		#region Skin

		protected override void AttachChildControls()
		{
			searchFor				= FindText("ForumDescription");
			searchTextTop           = (TextBox)FindControl("SearchTextTop");
			searchTextBottom        = (TextBox)FindControl("SearchTextBottom");
			searchButtonTop         = FindButton("SearchButtonTop");
			searchButtonBottom      = FindButton("SearchButtonBottom");
			searchDataList          = (DataList)FindControl("SearchDataList");
			pager                   = (Pager)FindControl("Pager");
			resultTotal             = (CurrentPage)FindControl("TotalResults");
			searchDuration          = FindText("SearchDuration");
			validatorTop			= (HtmlGenericControl)FindControl("SearchBoxValidatorTop");
			validatorBottom			= (HtmlGenericControl)FindControl("SearchBoxValidatorBottom");

			if(searchTextTop == null)
				throw new Exception("!danm!");

			InitializeChildControls();
		}

		private void InitializeChildControls()
		{
			cSContext = CSContext.Current;

			if(searchButtonTop != null)
			{
				searchButtonTop.Text    = ResourceManager.GetString("Search");
				searchButtonTop.Click += new EventHandler(Search_Click);
			}
			if(searchButtonBottom != null)
			{
				searchButtonBottom.Text = ResourceManager.GetString("Search");
				searchButtonBottom.Click += new EventHandler(Search_Click);
			}
			if(resultTotal != null)
				resultTotal.TextFormat  = ResourceManager.GetString("SearchResults_TotalResults");
			if(searchDuration != null)
				searchDuration.Text     = ResourceManager.GetString("SearchResults_SearchDuration");

			IText name = FindText("ForumName");
			if(name != null)
				name.Text = ResourceManager.GetString("Gallery_Search_Title");
			
			pager.PageSize = cSContext.SiteSettings.SearchPostsPerPage;

			searchDataList.ItemDataBound += new DataListItemEventHandler(searchDataList_ItemDataBound);
		}

		#endregion

		#region Event Overrides

		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			if(Page.Request.QueryString["f"] != null)
				searchSections = SectionsToSearchDecode(Page.Request.QueryString["f"]);
		}


		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);
			DataBind();
		}

		public override void DataBind()
		{
			base.DataBind();

			if(!Page.IsPostBack) 
			{
				if(searchTextTop != null)
					searchTextTop.Text = Page.Request.QueryString["q"];
				if(searchTextBottom != null)
					searchTextBottom.Text = searchTextTop.Text;
				searchUsers = UsersToDecode(Page.Request.QueryString["u"] );
			}
			
			BindSearch();
		}

		#endregion

		#region ItemDataBound

		private void searchDataList_ItemDataBound(object sender, DataListItemEventArgs e)
		{
			GalleryPost galleryPost = e.Item.DataItem as GalleryPost;

			switch(e.Item.ItemType)
			{
				case ListItemType.Item:
				case ListItemType.AlternatingItem:

					HyperLink pictureLink = (HyperLink) e.Item.FindControl("PictureLink");
					HyperLink galleryLink = (HyperLink) e.Item.FindControl("GalleryLink");
					HyperLink userLink = (HyperLink) e.Item.FindControl("UserLink");
					Literal postDate = (Literal) e.Item.FindControl("PostDate");

					Gallery gallery = Galleries.GetGallery( galleryPost.SectionID );

					if(pictureLink != null)
					{
						pictureLink.Text = galleryPost.Subject;
						pictureLink.NavigateUrl = GalleryUrls.Instance().ViewPicture( gallery.ApplicationKey, galleryPost );
					}

					if(galleryLink != null)
					{
						galleryLink.Text = gallery.Name;
						galleryLink.NavigateUrl = GalleryUrls.Instance().ViewGallery( gallery.ApplicationKey );
					}

					if(userLink != null)
					{
						userLink.Text = galleryPost.User.DisplayName;
						userLink.NavigateUrl = Globals.GetSiteUrls().UserProfile( galleryPost.AuthorID );
						userLink.Target = "_blank";
					}

					User user = cSContext.User;
					DateTime changedDate = galleryPost.PostDate;
					string dateFormat;

					if(!user.IsAnonymous)
					{
						changedDate = user.GetTimezone(changedDate);
						dateFormat = user.Profile.DateFormat;
					}
					else
						dateFormat = cSContext.SiteSettings.DateFormat;
					
					if(postDate != null)
                        postDate.Text = changedDate.ToString(dateFormat) + " " + changedDate.ToString(cSContext.SiteSettings.TimeFormat);

					break;
			}
		}

		#endregion

		#region Event Handlers

		public void Search_Click (Object sender, EventArgs e) 
		{
			bool isSearchTextInTopTextBox = true;

			// Which search text is being used?
			if( ((LinkButton) sender).ID != "SearchButtonTop" )
				isSearchTextInTopTextBox = false;

			// Set the text to the correct values
			if(isSearchTextInTopTextBox)
			{
				if(searchTextTop.Text.Trim() == string.Empty)
				{
					validatorTop.Visible = true;
					return;
				}
				else
				{
					validatorTop.Visible = false;
					searchTextBottom.Text = searchTextTop.Text;
				}
			}
			else
			{
				if(searchTextBottom.Text.Trim() == string.Empty)
				{
					validatorBottom.Visible = true;
					return;
				}
				else
				{
					validatorBottom.Visible = false;
					searchTextTop.Text = searchTextBottom.Text;
				}
			}
			DataBind();
		}
		#endregion

		#region Private Methods

		private void BindSearch() 
		{
			SearchResultSet searchResult;

			// Set the "search for" text
			searchFor.Text = string.Format(ResourceManager.GetString("SearchViewSimple_SearchFor"), Globals.HtmlEncode(searchTextTop.Text));

			// Get the search results
		    SearchQuery query = new SearchQuery();
			query.PageIndex = pager.PageIndex;
			query.PageSize = pager.PageSize;
			
			query.SectionsToSearch = searchSections;
			query.UsersToSearch = searchUsers;
			query.QueryText = searchTextTop.Text;
			query.ApplicationTypes = new ApplicationType[] {ApplicationType.Gallery };
			searchResult = CSSearch.Search(query);

			// Do we have search results?
			if(!searchResult.HasResults) 
				return;

			// Set the TotalRecords in the pager
			pager.TotalRecords = searchResult.TotalRecords;

			// Databind
			searchDataList.DataSource = searchResult.Posts;
			searchDataList.DataBind();

			// Setup the result total
			resultTotal.PageIndex = pager.PageIndex;
			resultTotal.TotalPages = pager.CalculateTotalPages();
			resultTotal.TotalRecords = pager.TotalRecords;
			pager.DataBind();

			if (searchResult.SearchDuration < 1)
				searchDuration.Text = string.Format(searchDuration.Text, "< 1");
			else
				searchDuration.Text = string.Format(searchDuration.Text, searchResult.SearchDuration);
		}

		private int[] UsersToDecode (string stringToDecode) 
		{
			UTF8Encoding decoder = new UTF8Encoding();
			int[] usersToSearch = null;

			try 
			{
				byte[] userList = Convert.FromBase64String( stringToDecode );
				string[] users = decoder.GetString( userList ).Split(',');
				usersToSearch = new int[users.Length];
				for(int i = 0; i<users.Length; i++)
					usersToSearch[i] = Int32.Parse(users[i]);
			} 
			catch 
			{
				usersToSearch = null;
			}

			return usersToSearch;
		}

		private static int[] SectionsToSearchDecode(string stringToDecode) 
		{
			CSContext cSContext = CSContext.Current;
			Hashtable galleries = Galleries.GetGalleries(cSContext, cSContext.User.UserID, false, true, false, false);
			UTF8Encoding decoder = new UTF8Encoding();
			string[] filteredSectionsToSearch = null;
			ArrayList verifiedSectionList = new ArrayList();

			// Convert the parameters from a base64 encoded string and then
			// into a string[]
			if (stringToDecode != string.Empty) 
			{
				// Attempt to decode the string
				try 
				{
					byte[] forumList = Convert.FromBase64String( stringToDecode );
					filteredSectionsToSearch = decoder.GetString( forumList ).Split(',');
				} 
				catch { filteredSectionsToSearch = null; }
			}

			// Get a verified list of only the forums the user has access to
			// if our forum string[] is null we get all the forums the user
			// has access to; otherwise the list is checked to ensure we only
			// get forums the user is allowed to see
			if(filteredSectionsToSearch == null) 
			{
				foreach(Gallery gallery in galleries.Values)
					verifiedSectionList.Add(gallery.SectionID);
			} 
			else 
			{
				foreach(string appKey in filteredSectionsToSearch) 
				{
					if(galleries[appKey] != null) 
						verifiedSectionList.Add( ((Gallery)galleries[appKey]).SectionID );
				}
			}

			return (int[])verifiedSectionList.ToArray(typeof(int));
		}

		#endregion

	}
}
